<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class PW_Form_validation extends CI_Form_validation
{

    public function alpha_extra($str, $extra)
    {
        return ( ! preg_match("/^([-a-z0-9{$extra}])+$/i", $str)) ? FALSE : TRUE;
    }

    /**
     * Return true if input string is Japanese Hiragana.
     *
     * @param string $str
     * @return boolean
     */
    public function hiragana($str)
    {
        return (!preg_match('/^([\p{Hiragana}]*)$/u', $str)) ? FALSE : TRUE;
//         return ( ! preg_match('/^[\x{3040}-\x{309F}]*$/u', $str)) ? FALSE : TRUE;
    }

    /**
     * Return true if input string is Japanese Furigana (1-byte Katakana).
     *
     * @param string $str
     * @return boolean
     */
    public function furigana($str)
    {
        return (!preg_match("/^(?:\xEF\xBD[\xA1-\xBF]|\xEF\xBE[\x80-\x9F])+$/", mb_convert_encoding($str, 'UTF-8'))) ? FALSE : TRUE;
    }

    /**
     * Return true if input string is Japanese.
     *
     * Note:
     *   U+4E00–U+9FBF Kanji
     *   U+3040–U+309F Hiragana
     *   U+30A0–U+30FF Katakana
     *
     * @param string $str
     * @return boolean
     */
    public function japanese($str)
    {
        return (!preg_match('/^([\p{Katakana}\p{Hiragana}\p{Han}]*)$/u', $str)) ? FALSE : TRUE;
        //         return (!preg_match('/^[\x{30A0}-\x{30FF}\x{3040}-\x{309F}\x{4E00}-\x{9FBF}\s]*$/u', $str)) ? FALSE : TRUE;
    }

    /**
     * Return true if input time matches a time pattern
     *
     * @param string $str
     * @param string $pattern
     * @return boolean
     */
    public function datetime_pattern($str, $pattern)
    {
        if ($pattern == '') {
            $pattern = 'Y-m-d H:i:s';
        }

        return (date($pattern, strtotime($str)) != $str) ? FALSE : TRUE;
    }

    /**
     * Return true if input date matches a date pattern
     *
     * @param string $str
     * @param string $pattern
     * @return boolean
     */
    public function date_pattern($str, $pattern)
    {
        if ($pattern == '') {
            $pattern = 'Y-m-d';
        }

        return (date($pattern, strtotime($str)) != $str) ? FALSE : TRUE;
    }

    /**
     * Return true if input captcha code matches code store in the session.
     *
     * @param string $str
     * @param string $session - session name
     * @return boolean
     */
    public function captcha($str, $session)
    {
        $CI =& get_instance();

        return ($str != strtolower($CI->session->flashdata($session))) ? FALSE : TRUE;
    }

    /**
     * Return true if given time is after a period from now.
     *
     * Period:
     *   - 'now':  compare to current time
     *   - [period]:
     *     + P[days]D:  compare to a period of days
     *     + T[hours]H: compare to a period of hours
     *
     * @param string $value - value to check
     * @param string $period
     * @param string $timeInput [option] - time for exception (used in updating, time of input to check)
     * @return boolean
     */
    public function after_period($str, $period) {

        $dateObj = new DateTime();
        switch (true) {
            case (strtolower($period) == 'now'):
                break;
            case (substr($period, 0, 1) == '('):
                $period = substr($period, 1, -1);
                $dateObj->sub(new DateInterval($period));
                break;
            default:
                $dateObj->add(new DateInterval($period));
                break;
        }
        $dateTime = $dateObj->format('Y-m-d H:i:s');

        return (strtotime($str) < strtotime($dateTime)) ? FALSE : TRUE;
    }

    /**
     * Return true if given time is before a period from now.
     *
     * Period:
     *   - 'now':  compare to current time
     *   - [period]:
     *     + P[days]D:  compare to a period of days
     *     + T[hours]H: compare to a period of hours
     *
     * @param string $value - value to check
     * @param string $period
     * @param string $timeInput [option] - time for exception (used in updating, time of input to check)
     * @return boolean
     */
    public function before_period($str, $period) {

        $dateObj = new DateTime();
        switch (true) {
            case (strtolower($period) == 'now'):
                break;
            case (substr($period, 0, 1) == '('):
                $period = substr($period, 1, -1);
                $dateObj->sub(new DateInterval($period));
                break;
            default:
                $dateObj->add(new DateInterval($period));
                break;
        }
        $dateTime = $dateObj->format('Y-m-d H:i:s');

        return (strtotime($str) > strtotime($dateTime)) ? FALSE : TRUE;
    }

    /**
     * Return true if input select option is in an global array.
     *
     * Can use only declare in advance a $GLOBALS variable which key is the array name.
     *
     * @param string $str
     * @param string $arrayName
     * @return boolean
     */
    public function in_options($str, $arrayName) {
        return (!in_array($str, $GLOBALS[$arrayName])) ? FALSE : TRUE;
    }

    /**
     * Match one field to another
     *
     * @access    public
     * @param    string
     * @param    field
     * @return    bool
     */
    public function is_unique($str, $field) {

        list($field, $id)=explode('-', $field);
        list($table, $field)=explode('.', $field);
        $query = $this->CI->db->limit(1)->get_where($table, array($field => $str));
        if ($query->num_rows() === 0) {
            return true;
        }
        if ($id && ($id == $query->row()->id)) {
            return true;
        }
        return false;
    }

    /**
     * Match one field to another
     *
     * @access    public
     * @param    string
     * @param    field
     * @return    bool
     */
    public function is_exist($str, $field) {

        if ($this->is_unique($str, $field) == true) {
            return false;
        }

        return true;
    }

    /**
     * Validate URL
     *
     * @access    public
     * @param    string
     * @return    string
     */
    public function valid_url($url)
    {
        $pattern = "/^(http(?:s)?\:\/\/[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*\.[a-zA-Z]{2,6}(?:\/?|(?:\/[\w\-]+)*)(?:\/?|\/\w+\.[a-zA-Z]{2,4}(?:\?[\w]+\=[\w\-]+)?)?(?:\&[\w]+\=[\w\-]+)*)$/";

        if (!preg_match($pattern, $url))
        {
            return false;
        }

        return true;
    }

    /**
     * Test string end with string
     *
     * @access    public
     * @param    string
     * @return    string
     */
    public function end_with($str, $val)
    {
        if( ! preg_match("/{$val}$/i", $str))
        {
            $this->set_message('end_with',"%s should end with $val.");
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }

    /**
     * Tests the file extension for valid file types
     *
     * @param mixed $file
     * @param mixed $type
     */
    function file_allowed_type($file,$type)
    {
        //is type of format a,b,c,d? -> convert to array
        $exts = explode(',',$type);

        //is $type array? run self recursively
        if(count($exts)>1)
        {
            foreach($exts as $v)
            {
                $rc = $this->file_allowed_type($file,$v);
                if($rc===TRUE)
                {
                    return TRUE;
                }
            }
        }

        //is type a group type? image, application, word_document, code, zip .... -> load proper array
        $ext_groups = array();
        $ext_groups['image'] = array('jpg','jpeg','gif','png');
        $ext_groups['application'] = array('exe','dll','so','cgi');
        $ext_groups['php_code'] = array('php','php4','php5','inc','phtml');
        $ext_groups['word_document'] = array('rtf','doc','docx');
        $ext_groups['compressed'] = array('zip','gzip','tar','gz');

        if(array_key_exists($exts[0],$ext_groups))
        {
            $exts = $ext_groups[$exts[0]];
        }

        //get file ext
        $file_ext = strtolower(strrchr($file['name'],'.'));
        $file_ext = substr($file_ext,1);

        if(!in_array($file_ext,$exts))
        {
            $this->set_message('file_allowed_type',"%s should be $type.");
            return false;
        }
        else
        {
            return TRUE;
        }
    }
}

?>